﻿#include "OperGraphPost.h"

// APP
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppSettings.h"
#include "FITK_Kernel/FITKAppFramework/FITKRunTimeSetting.h"

// Global data
#include "FITK_Kernel/FITKCore/FITKDataRepo.h"

// Graph widget and object
#include "FITK_Component/FITKRenderWindowVTK/FITKGraph3DWindowVTK.h"
#include "FITK_Component/FITKAcousticsVTKGraphAdaptor/FITKAcousticsVTKGraphObject3DPost.h"
#include "FITK_Component/FITKAcousticsVTKGraphAdaptor/FITKAcousticsVTKGraphObjectScalarBars.h"

// Graph data manager
#include "GraphDataProvider/GraphProviderManager.h"
#include "GraphDataProvider/GraphModelProvider.h"
#include "GraphDataProvider/GraphMarkProvider.h"

// GUI
#include "GUIFrame/MainWindow.h"
#include "GUIFrame/CentralWidget.h"
#include "GUIWidget/GraphArea.h"
#include "GUIWidget/PreWindow3D.h"
#include "FITK_Component/FITKWidget/FITKMdiArea.h"

namespace GUIOper
{
    void OperGraphPost::updatePostData(QHash<QString, float> & postData, QString name, double rangeMin, double rangeMax,
        Comp::FITKGraph3DWindowVTK* graphWidget)
    {
        // 检查三维窗口。
        if (!graphWidget)
        {
            graphWidget = getGraphWidget();
        }

        if (!graphWidget)
        {
            return;
        }

        Exchange::FITKAcousticsVTKGraphObjectScalarBars* scalarBarsObj = 
            Exchange::FITKAcousticsVTKGraphObjectScalarBars::SafeDownCast(getScalarBarGraphObj(graphWidget));
        if (!scalarBarsObj)
        {
            return;
        }

        // 获取SEA子系统（梁、板、声腔）可视化对象。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = getPostGraphObjs(graphWidget);

        // 设置后处理数据并开启云图渲染。
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            Exchange::FITKAcousticsVTKGraphObject3DPost* pObj = Exchange::FITKAcousticsVTKGraphObject3DPost::SafeDownCast(obj);
            if (!pObj)
            {
                continue;
            }

            pObj->setPostData(name, postData);
            pObj->updateByPostCellData(name, rangeMin, rangeMax);
        }

        // 刷新色棒。
        scalarBarsObj->removeFromGraphWidget();
        scalarBarsObj->setInfo(name, rangeMin, rangeMax);
        scalarBarsObj->setVisibleByPort(true);
        graphWidget->fastAddObject(scalarBarsObj->getRenderLayer(), scalarBarsObj);

        // 刷新渲染。
        reRender(graphWidget);
    }

    void OperGraphPost::setEnableLogScale(bool isOn, Comp::FITKGraph3DWindowVTK* graphWidget)
    {
        // 检查三维窗口。
        if (graphWidget == nullptr){
            graphWidget = getGraphWidget();
        }

        if (graphWidget == nullptr){
            return;
        }

        //修改Bar映射方式
        Exchange::FITKAcousticsVTKGraphObjectScalarBars* scalarBarsObj = Exchange::FITKAcousticsVTKGraphObjectScalarBars::SafeDownCast(getScalarBarGraphObj(graphWidget));
        if (scalarBarsObj){
            scalarBarsObj->setEnableLogScale(isOn);
        }

        // 获取SEA子系统（梁、板、声腔）可视化对象，修改色棒映射
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = getPostGraphObjs(graphWidget);
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs){
            Exchange::FITKAcousticsVTKGraphObject3DPost* pObj = Exchange::FITKAcousticsVTKGraphObject3DPost::SafeDownCast(obj);
            if (pObj == nullptr){
                continue;
            }
            pObj->setEnableLogScale(isOn);
        }

        //刷新渲染。
        reRender(graphWidget);
    }

    void OperGraphPost::setColorScalarNumber(int num, Comp::FITKGraph3DWindowVTK * graphWidget)
    {
        if (graphWidget == nullptr) {
            graphWidget = getGraphWidget();
        }

        //获取SEA子系统（梁、板、声腔）可视化对象
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = getPostGraphObjs(graphWidget);
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs) {
            Exchange::FITKAcousticsVTKGraphObject3DPost* postObj = Exchange::FITKAcousticsVTKGraphObject3DPost::SafeDownCast(obj);
            if (postObj == nullptr) {
                continue;
            }
            postObj->setScalarNumber(num);
        }

        reRender(graphWidget);
    }

    void OperGraphPost::disablePostData(Comp::FITKGraph3DWindowVTK* graphWidget)
    {
        // 检查三维窗口。
        if (!graphWidget)
        {
            graphWidget = getGraphWidget();
        }

        if (!graphWidget)
        {
            return;
        }

        Exchange::FITKAcousticsVTKGraphObjectScalarBars* scalarBarsObj =
            Exchange::FITKAcousticsVTKGraphObjectScalarBars::SafeDownCast(getScalarBarGraphObj(graphWidget));
        if (!scalarBarsObj)
        {
            return;
        }

        // 获取SEA子系统（梁、板、声腔）可视化对象。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = getPostGraphObjs(graphWidget);

        // 关闭云图渲染。
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            Exchange::FITKAcousticsVTKGraphObject3DPost* pObj = Exchange::FITKAcousticsVTKGraphObject3DPost::SafeDownCast(obj);
            if (!pObj)
            {
                continue;
            }

            pObj->updateByDataColor();
        }

        // 刷新色棒。
        scalarBarsObj->setVisible(false);

        // 刷新渲染。
        reRender(graphWidget);
    }

    void OperGraphPost::setRangeColor(QColor minRangeColor, QColor maxRangeColor, double transparency, Comp::FITKGraph3DWindowVTK * graphWidget)
    {
        if (graphWidget == nullptr) {
            graphWidget = getGraphWidget();
        }

        if (graphWidget == nullptr) {
            return;
        }

        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = getPostGraphObjs(graphWidget);
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs) {
            Exchange::FITKAcousticsVTKGraphObject3DPost* postObj = Exchange::FITKAcousticsVTKGraphObject3DPost::SafeDownCast(obj);
            if (postObj == nullptr) {
                continue;
            }
            postObj->setRangeColor(minRangeColor, maxRangeColor, transparency);
        }

        reRender(graphWidget);
    }

    void OperGraphPost::setAboveRangeColor(QColor color, double transparency, Comp::FITKGraph3DWindowVTK * graphWidget)
    {
        if (graphWidget == nullptr) {
            graphWidget = getGraphWidget();
        }

        if (graphWidget == nullptr) {
            return;
        }

        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = getPostGraphObjs(graphWidget);
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs) {
            Exchange::FITKAcousticsVTKGraphObject3DPost* postObj = Exchange::FITKAcousticsVTKGraphObject3DPost::SafeDownCast(obj);
            if (postObj == nullptr) {
                continue;
            }
            postObj->setAboveRangeColor(color, transparency);
        }

        reRender(graphWidget);
    }

    void OperGraphPost::setBelowRangeColor(QColor color, double transparency, Comp::FITKGraph3DWindowVTK * graphWidget)
    {
        if (graphWidget == nullptr) {
            graphWidget = getGraphWidget();
        }

        if (graphWidget == nullptr) {
            return;
        }

        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = getPostGraphObjs(graphWidget);
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs) {
            Exchange::FITKAcousticsVTKGraphObject3DPost* postObj = Exchange::FITKAcousticsVTKGraphObject3DPost::SafeDownCast(obj);
            if (postObj == nullptr) {
                continue;
            }
            postObj->setBelowRangeColor(color, transparency);
        }

        reRender(graphWidget);
    }

    Comp::FITKGraph3DWindowVTK* OperGraphPost::getGraphWidget()
    {
        // 获取主窗口。
        GUI::MainWindow* mainWindow = FITKAPP->getGlobalData()->getMainWindowT<GUI::MainWindow>();
        if (mainWindow == nullptr){
            return nullptr;
        }

        // 获取中心区域。
        GUI::CentralWidget* centralWidget = mainWindow->getCentralWidget();
        if (centralWidget == nullptr){
            return nullptr;
        }

        // 获取3D区域。
        GUI::GraphArea* gArea = centralWidget->getGraphArea();
        if (gArea == nullptr){
            return nullptr;
        }

        //获取当前激活的窗口
        GUI::PreWindow3D* widget3D = nullptr;
        widget3D = dynamic_cast<GUI::PreWindow3D*>(gArea->getCurrentSubWin());
        if (widget3D == nullptr) {
            widget3D = dynamic_cast<GUI::PreWindow3D*>(gArea->getFirstWindow(GUI::GraphAbstractSubWin::SubWinType::Pre3D));
        }

        if (widget3D == nullptr) {
            return nullptr;
        }

        //获取3D可视化区域
        Comp::FITKGraph3DWindowVTK* graphWidget = widget3D->getRenderWindow();
        if (graphWidget == nullptr){
            return nullptr;
        }

        return graphWidget;
    }

    void OperGraphPost::reRender(Comp::FITKGraph3DWindowVTK* graphWidget, bool fitView)
    {
        if (!graphWidget)
        {
            return;
        }

        if (fitView)
        {
            graphWidget->fitView();
        }
        else
        {
            graphWidget->reRender();
        }
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> OperGraphPost::getPostGraphObjs(Comp::FITKGraph3DWindowVTK* graphWidget)
    {
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs;

        // 检查三维窗口。
        if (!graphWidget)
        {
            graphWidget = getGraphWidget();
        }

        if (!graphWidget)
        {
            return objs;
        }

        // 获取模型与符号可视化对象管理器。
        GraphData::GraphModelProvider* modelProvider = GraphData::GraphProviderManager::getInstance()->getModelProvider(graphWidget);
        GraphData::GraphMarkProvider* markProvider = GraphData::GraphProviderManager::getInstance()->getMarkProvider(graphWidget);
        if (!modelProvider || !markProvider)
        {
            return objs;
        }

        // 获取SEA子系统（梁、板、声腔）可视化对象。
        objs << modelProvider->getAllSEABeamGraphObjects(true);
        objs << modelProvider->getAllSEAShellGraphObjects(true);
        objs << modelProvider->getAllSEACavityGraphObjects(true);

        return objs;
    }

    Exchange::FITKAcousticsVTKGraphObject3D* OperGraphPost::getScalarBarGraphObj(Comp::FITKGraph3DWindowVTK* graphWidget)
    {
        // 检查三维窗口。
        if (!graphWidget)
        {
            graphWidget = getGraphWidget();
        }

        if (!graphWidget)
        {
            return nullptr;
        }

        // 获取符号可视化对象管理器。
        GraphData::GraphMarkProvider* markProvider = GraphData::GraphProviderManager::getInstance()->getMarkProvider(graphWidget);
        if (!markProvider)
        {
            return nullptr;
        }

        return markProvider->getScalarBarsGraphObject();
    }
}  // namespace EventOper
